package sc;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

public class Member extends BasePanel
{
	private static final long serialVersionUID = 1L;
	private static Map<String, Member> membersByName = new HashMap<String, Member>();
	private static Map<String, Member> membersByID = new HashMap<String, Member>();
	
	private final static Color topleft_offline;
	private final static Color bottomright_offline;
	private final static Color topleft_online;
	private final static Color bottomright_online;
	private final static Color online_name;
	
	private final static Font nameFont;

	private final static JPopupMenu popupMenu;
	private static String popupMenuMemberId;
	
	private final static Image companionscross;
	private final static Image starofallegiance;
	private final static Image platinumhammer;
	private final static Image ventrilo;
	private final static Image inchat;
	private final static Image offline;
	private final static Image selectImage;
	
	private static int sortBy = 0;
	private static Member userMember;

	private String name;
	private String member_id;
	private boolean inVent;
	private boolean onForum;
	private boolean inChat;
	private String race;
	private boolean sex;
	private String ip;
	private boolean isUser;
	private String rank;
	private String ventpass;
	private String venttime;
	private String ventping;
	private String award;
	private Image avatar;
	private Image ranklogo;
	private boolean selected;

	static
	{
		topleft_offline = new Color(0.6f, 0.6f, 0.6f);
		bottomright_offline = new Color(0.5f, 0.5f, 0.5f);
		topleft_online = new Color(1f, 0.1f, 0.1f);
		bottomright_online = new Color(0.9f, 0.9f, 0.5f);
		nameFont = new Font("SansSerif", Font.PLAIN, 16);
		online_name = new Color(1f, 1f, 1f);
		
		companionscross = Images.getImage("/images/companionscross.png");
		starofallegiance = Images.getImage("/images/starofallegiance.png");
		platinumhammer = Images.getImage("/images/platinumhammer.png");
		ventrilo = Images.getImage("/images/ventrilo.png");
		inchat = Images.getImage("/images/inchat.png");
		offline = Images.getImage("/images/offline.png");
		selectImage = Images.getImage("/images/selected.png");
		
		ActionListener menuListener = new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				String cmd = e.getActionCommand();
				if (cmd == "Profile")
					OpenURL.openProfile(Member.popupMenuMemberId);
				else if (cmd == "Info")
				{
				}
				else if (cmd == "Send Message")
					SendMessage.open(Member.userMember.member_id, Member.popupMenuMemberId);
			}
		};
		
		JPopupMenu.setDefaultLightWeightPopupEnabled(false);
		popupMenu = new JPopupMenu("Menu");
        Icon icon = new ImageIcon(Images.getImage("/images/profile.png"));
		JMenuItem item = new JMenuItem("Profile", icon);
		item.addActionListener(menuListener);
		popupMenu.add(item);
		icon = new ImageIcon(SendMessage.icon);
		item = new JMenuItem("Send Message", icon);
		item.addActionListener(menuListener);
		popupMenu.add(item);
	}

	public static Member getMemberByName(String name, boolean create)
	{
		// Fuzzy match member names to fix problem with Vent names being slightly
		// different to forum names
		String namelc = name.toLowerCase();
		for (String key : membersByName.keySet())
		{
			String keylc = key.toLowerCase();
			int len = 5;
			if (keylc.length() < len) len = keylc.length();
			if (namelc.length() < len) len = namelc.length();
			if (keylc.startsWith(namelc.substring(0, len))
				|| keylc.endsWith(namelc.substring(name.length()-len)))
			{
				return membersByName.get(key);
			}
		}
		if (create == true)
			membersByName.put(name, new Member(name));
		else
			return null;
		return membersByName.get(name);
	}

	public static Member getMemberByID(String id)
	{
		return membersByID.get(id);
	}

	public static Collection<Member> getAllMembers()
	{
		return membersByName.values();
	}

	public Member(String name)
	{
		this.name = name;
		setPreferredSize(new Dimension(100, 20));
		add(popupMenu);
		award = "";
		avatar = null;
		ranklogo = null;
		selected = false;
	}

	public void sortByName()
	{
		if (online())
			sortValue("0" + name);
		else
			sortValue("6" + name);
		sortBy = 0;
	}

	public void sortByChat()
	{
		if (online())
			if (inChat())
				sortValue("00" + name);
			else
				sortValue("01" + name);
		else
			sortValue("6" + name);
		sortBy = 1;
	}

	public void sortByVent()
	{
		if (online())
			if (inVent())
				sortValue("00" + name);
			else
				sortValue("01" + name);
		else
			sortValue("6" + name);
		sortBy = 2;
	}

	public void sortByRank()
	{
		sortValue("0" + name);
		if (this.rank.equals("Member"))
			sortValue("1" + name);
		else if (this.rank.equals("Unknown"))
			sortValue("6" + name);
		sortBy = 3;
	}

	public void updateSortValue()
	{
		if (sortBy == 0)
			sortByName();
		else if (sortBy == 1)
			sortByChat();
		else if (sortBy == 2)
			sortByVent();
		else if (sortBy == 3)
			sortByRank();
	}

	public boolean inVent(boolean inVent)
	{
		if (!Information.firstUpdate)
		{
			if (Configuration.notifyVentArrivals() && this.inVent == false
					&& inVent == true)
				Tray.event(this.name + " entered vent");
			else if (Configuration.notifyVentExits() && this.inVent == true
					&& inVent == false)
				Tray.event(this.name + " left vent");
		}
		this.inVent = inVent;
		updateSortValue();
		return this.inVent;
	}

	public boolean inVent()
	{
		return this.inVent;
	}

	public boolean onForum(boolean onForum)
	{
		if (!Information.firstUpdate)
		{
			if (Configuration.notifyForumArrivals() && this.onForum == false
					&& onForum == true)
				Tray.event(this.name + " entered forums");
			else if (Configuration.notifyForumExits() && this.onForum == true
					&& onForum == false)
				Tray.event(this.name + " left forums");
		}
		this.onForum = onForum;
		updateSortValue();
		return this.onForum;
	}

	public boolean onForum()
	{
		return this.onForum;
	}

	public boolean inChat(boolean inChat)
	{
		if (!Information.firstUpdate)
		{
			if (Configuration.notifyChatArrivals() && this.inChat == false
					&& inChat == true)
				Tray.event(this.name + " entered chat");
			else if (Configuration.notifyChatExits() && this.inChat == true
					&& inChat == false)
				Tray.event(this.name + " left chat");
		}
		this.inChat = inChat;
		updateSortValue();
		return this.inChat;
	}

	public boolean inChat()
	{
		return this.inChat;
	}

	public boolean online()
	{
		return this.inVent || this.onForum || this.inChat;
	}

	public void setMemberId(String member_id)
	{
		if (membersByID.containsKey(this.member_id))
			membersByID.remove(this.member_id);
		this.member_id = member_id;
		membersByID.put(member_id, this);

	}

	public String getMemberId()
	{
		return this.member_id;
	}

	public String getName()
	{
		return this.name;
	}

	public String getAvatarPath()
	{
		if (race.equals("Human"))
		{
			if (sex)
				return "/images/human_male.png";
			return "/images/human_female.png";
		}
		if (race.equals("Dwarf"))
		{
			if (sex)
				return "/images/dwarf_male.png";
			return "/images/dwarf_female.png";
		}
		if (race.equals("Mirdain"))
		{
			if (sex)
				return "/images/mirdain_male.png";
			return "/images/mirdain_female.png";
		}
		if (race.equals("Alfar"))
			return "/images/alfar_male.png";
		if (race.equals("Ork"))
			return "/images/ork_male.png";

		return "/images/unknown.png";
	}

	public void setRace(String race)
	{
		if (race.equals("H"))
			this.race = "Human";
		else if (race.equals("D"))
			this.race = "Dwarf";
		else if (race.equals("M"))
			this.race = "Mirdain";
		else if (race.equals("A"))
			this.race = "Alfar";
		else if (race.equals("O"))
			this.race = "Ork";
		else
			this.race = "Unknown";
		
		this.avatar = Images.getImage(getAvatarPath());
	}

	public void setSex(String sex)
	{
		this.sex = sex.equals("M");
		this.avatar = Images.getImage(getAvatarPath());
	}

	public void setIP(String ip)
	{
		this.ip = ip;
	}

	public String getIP()
	{
		return ip;
	}

	public void setRank(String rank)
	{
		this.ranklogo = Images.getImage("/images/lords.png");
		if (rank.equals("Go"))
			this.rank = "Governer General";
		else if (rank.equals("Ge"))
			this.rank = "General";
		else if (rank.equals("Ch"))
			this.rank = "Chancellor";
		else if (rank.equals("Tr"))
			this.rank = "Trade Lord";
		else if (rank.equals("Sq"))
			this.rank = "Squad Leader";
		else if (rank.equals("Se"))
			this.rank = "Senator";
		else if (rank.equals("Me"))
		{
			this.rank = "Member";
			this.ranklogo = Images.getImage("/images/harlequin.png");
		}
		else {
			this.rank = "Unknown";
			this.ranklogo = null;
		}
	}

	public void setVentPass(String ventpass)
	{
		this.ventpass = ventpass;
		OpenURL.setVentCredentials(name, ventpass);
	}

	public String getVentPass()
	{
		return ventpass;
	}

	public void isUser(boolean isuser)
	{
		this.isUser = isuser;
		
		if (isuser)
		{
			TopPanel.enableOpenForum(true);		
			TopPanel.enableJoinChat(true);
			TopPanel.enableJoinVent(true);
			Tray.enableOpenForum(true);		
			Tray.enableJoinChat(true);
			Tray.enableJoinVent(true);
			Member.userMember = this;
		}
	}
	
	public boolean isUser()
	{
		return isUser;
	}

	public void setAward(String award)
	{
		if (award.equals("1"))
			this.award = "The Companion's Cross";
		else if (award.equals("2"))
			this.award = "Star of Allegiance";
		else if (award.equals("3"))
			this.award = "The Platinum Hammer";
	}
	
	public static Member userMember()
	{
		return Member.userMember;
	}

	public void mouseEntered(MouseEvent e)
	{
		super.mouseEntered(e);
		selected = true;
		repaint();
	}

	public void mouseExited(MouseEvent e)
	{
		super.mouseExited(e);
		selected = false;
		repaint();
	}
	
	public void mousePressed(MouseEvent e)
	{
		super.mousePressed(e);
		Member.popupMenuMemberId = member_id;
		popupMenu.show(this, e.getX() - 5, e.getY() + 2);
	}

	public void mouseMoved(MouseEvent e)
	{
		super.mouseMoved(e);
		
		int w = getWidth();
		int x = e.getX();
		
		if (x < 30)
			setToolTipText(race);
		else if (!award.equals("") && x > w - 80 && x < w - 60)
			setToolTipText(award);
		else if (inVent() && x > w - 60 && x < w - 40)
			setToolTipText("Ping: " + ventping + ", Connected: " + venttime);
		else if (inChat() && x > w - 40 && x < w - 20)
			setToolTipText("In Chat");
		else if (x > w - 20 && !(this.rank.equals("Member") || this.rank.equals("Unknown")))
			setToolTipText(rank);
		else
			setToolTipText(null);
	}
	
	public static void hidePopupMenu()
	{
		Member.popupMenu.setVisible(false);
		Member.popupMenuMemberId = null;
	}
	
	@Override
	protected void paintComponent(Graphics g)
	{
		int w = getWidth();
		int h = getHeight();
		GradientPaint gp;
		width(w);

		// Gradient fill panel
		if (online())
			gp = new GradientPaint(50, 0, topleft_online, 140, h,
					bottomright_online);
		else
			gp = new GradientPaint(130, 0, topleft_offline, 140, h,
					bottomright_offline);

		((Graphics2D) g).setPaint(gp);
		g.fillRect(0, 0, w, h);

		g.setColor(bottomright_offline);
		g.drawLine(0, h - 1, w, h - 1);
		
		if ((selected || Member.popupMenuMemberId == member_id) && selectImage != null)
		{
			for (int x = 0; x < w; x += 30)
				g.drawImage(selectImage, x, -3, this);
		}

		// Avatar
		if (avatar != null)
			g.drawImage(avatar, 0, -3, this);
		if (!online())
			g.drawImage(offline, 0, -3, this);

		// Members name
		g.setFont(nameFont);
		
		if (online())
		{
			g.setColor(Color.BLACK);
			g.drawString(getName(), 35, 16);
		}
		g.setColor(online_name);
		g.drawString(getName(), 34, 15);
		
		if (award.equals("The Companion's Cross") && companionscross != null)
			g.drawImage(companionscross, w - 80, 1, this);
		else if (award.equals("Star of Allegiance") && starofallegiance != null)
			g.drawImage(starofallegiance, w - 80, 1, this);
		else if (award.equals("The Platinum Hammer") && platinumhammer != null)
			g.drawImage(platinumhammer, w - 80, 1, this);

		// Status icons
		if (online())
		{
			if (inVent() && ventrilo != null)
				g.drawImage(ventrilo, w - 60, 1, this);
			if (inChat() && inchat != null)
				g.drawImage(inchat, w - 40,	1, this);
		}

		if (ranklogo != null)
			g.drawImage(ranklogo, w - 20,	0, this);
		
		if (!online() && !selected && offline != null)
		{
			for (int x = 30; x < w; x += 30)
				g.drawImage(offline, x, -3, this);
		}
			
	}

	public void ventInfo(String time, String ping)
	{
		this.venttime = time;
		this.ventping = ping;
	}
}
